﻿namespace MEF_Test.Bricks
{
    using System;
    using System.Collections.Generic;
    using System.Configuration;

    public class MappingsCollection : ConfigurationElementCollection
    {
        #region Methods

        /// <summary>
        /// When overridden in a derived class, creates a new <see cref="T:System.Configuration.ConfigurationElement"/>.
        /// </summary>
        /// <returns>
        /// A new <see cref="T:System.Configuration.ConfigurationElement"/>.
        /// </returns>
        protected override ConfigurationElement CreateNewElement()
        {
            return new MappingConfigElement();
        }

        /// <summary>
        /// Gets the element key for a specified configuration element when overridden in a derived class.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>.
        /// </returns>
        /// <param name="element">The <see cref="T:System.Configuration.ConfigurationElement"/> to return the key for. </param>
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((MappingConfigElement)element).Contract;
        }

        #endregion

        /// <summary>
        /// Adds a mapping between a contract and a type.
        /// </summary>
        /// <param name="contract">The contract.</param>
        /// <param name="type">The type.</param>
        public void AddMapping(string contract, string type)
        {
            BaseAdd(new MappingConfigElement(contract, type));
        }

        /// <summary>
        /// Gets the <see cref="MEF_Test.Bricks.MappingConfigElement"/> with the specified name.
        /// </summary>
        /// <value></value>
        new public MappingConfigElement this[string Name]
        {
            get
            {
                return (MappingConfigElement)BaseGet(Name);
            }
        }

        /// <summary>
        /// Finds the <see cref="MappingConfigElement"/>s matching the specified predicate.
        /// </summary>
        /// <param name="predicate">The predicate.</param>
        /// <returns>An enumeration of the <see cref="MappingConfigElement"/> matching the predicate.</returns>
        public MappingConfigElement Find(Func<MappingConfigElement, bool> predicate)
        {
            foreach (MappingConfigElement mapping in this)
            {
                if (predicate(mapping))
                {
                    return mapping;
                }
            }

            return null;
        }

        /// <summary>
        /// Gets the mappings dictionary.
        /// </summary>
        /// <returns></returns>  
        public Dictionary<string, string> GetMappingsDictionary()
        {
            var dictionary = new Dictionary<string, string>();

            foreach (MappingConfigElement pair in this)
            {
                dictionary.Add(pair.Contract, pair.Type);
            }
            return dictionary;
        }
    }
}